﻿using System;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
//using System.Collections;
//using VoxelBlock.VoxelBlock3D;
//using VoxelBlock;using Vector3Int = VoxelBlock.Vector3Int;
//using Net_framework_4.System;

namespace VoxelBlock.VoxelBlock3D
{

    public class DrawVoxel3DCoreManager
    {
        public class DrawVoxel3DCoreValue
        {
            public GameObject component;
            public UIItemTransformUnitComponent ui;
            public ProxyOperation proxy;
            public string name;
        }
        
        public Dictionary<DrawVoxel3DCore, DrawVoxel3DCoreValue> allCore = new Dictionary<DrawVoxel3DCore, DrawVoxel3DCoreValue>();


        public DrawVoxel3DCore mainDrawVoxel3DCore = null;
        public DrawVoxel3DCoreValue mainDrawVoxel3DCoreValue = null;
        public DrawVoxel3DCoreManager(string name, DrawVoxel3DCore core, ProxyOperation proxy, GameObject component, UIItemTransformUnitComponent ui)
        {
            DrawVoxel3DCoreValue value = new DrawVoxel3DCoreValue();
            value.component = component;
            value.proxy = proxy;
            value.name = name;
            value.ui = ui;
            allCore[core] = value;
            mainDrawVoxel3DCoreValue = value;
            mainDrawVoxel3DCore = core;
        }

        public void Add(string name, DrawVoxel3DCore core, ProxyOperation proxy, GameObject component, UIItemTransformUnitComponent ui)
        {
            DrawVoxel3DCoreValue value = new DrawVoxel3DCoreValue();
            value.component = component;
            value.proxy = proxy;
            value.name = name;
            value.ui = ui;
            allCore[core] = value;
        }

        public void ClearAll()
        {
            List<UIItemTransformUnitComponent> listUIItemTransformUnitComponent = new List<UIItemTransformUnitComponent>();

            foreach (var item in allCore)
            {
                if (item.Value.name.Equals("Main"))
                {
                    mainDrawVoxel3DCore = item.Key;
                    mainDrawVoxel3DCoreValue = item.Value;
                }
                else
                {
                    item.Key.Clear();
                    listUIItemTransformUnitComponent.Add(item.Value.ui);
                }

                //item.Key.Clear();
                //DrawVoxel3DCoreValue value = item.Value;
                //if (value.proxy != null)
                //{
                //    value.proxy.Clear();
                //}
            }
            foreach (var item in listUIItemTransformUnitComponent)
            {
                item.Delete();
            }
            allCore.Clear();
            //if (mainDrawVoxel3DCore != null)
            //{

            //}
            mainDrawVoxel3DCoreValue.component.transform.root.position = new Vector3(0, 0, 0);
            allCore[mainDrawVoxel3DCore] = mainDrawVoxel3DCoreValue;
        }
        public void Remove(DrawVoxel3DCore core)
        {
            ProxyOperation proxy = allCore[core].proxy;
            if (proxy != null)
            {
                proxy.Clear();
            }
            core.Clear();
            allCore.Remove(core);
        }
    }

    public class OperateCreate3D
    {
        bool isTempEditor = false;
        public DrawVoxel3DCoreManager drawVoxel3DCoreManager;

        #region 颜色机制

        //private Texture2D automaticSwatchesColorTexture2D;

        //public void SetNowSelectUVKeyAndColor(int selectUVKey)
        //{
        //    Color color = automaticSwatchesColor[selectUVKey].ToColor();
        //    ReadColorAction(color);
        //    nowSelectUVKey = selectUVKey;
        //    nowSelectColor = color;
        //}

        //public void SetNowSelectColor(Color selectColor)
        //{
        //    nowSelectColor = selectColor;
        //    nowSelectUVKey = automaticSwatchesColor.SelectColor(selectColor);
        //}

        //private Color nowSelectColor;
        //public Color GetNowSelectColor()
        //{
        //    return nowSelectColor;
        //}
        //public Action<Color> ReadColorAction = (color) => { Debug.Log(color); };

        #endregion



        /// <summary>
        /// 一片操作时候的碰撞体
        /// </summary>
        GameObject meshSliceCollider;


        //List<Vector3Int> allSelectVoxel = new List<Vector3Int>();

        Transform mainCameraY;

        Material tempMaterial;

        /// <summary>
        /// 历史记录API
        /// </summary>
        //public HistoryRecordAPI<SerializeVoxelDatas, VoxelCategories.Operation> nowHistoryRecord;

        HistoryRecordAPI<SerializeVoxelDatas, VoxelCategories.Operation> mainHistoryRecord;
        //HistoryRecordAPI<SerializeVoxelDatas, VoxelCategories.Operation> tempHistoryRecord;
        ProxyOperation mainProxyOperation;
        public ProxyOperation nowProxyOperation;
        //ProxyOperation tempProxyOperation;

        bool isOperation = true;


        OperationImplement nowOperationImplement;

        OperationImplementBrushAdd operationImplementBrushAdd;

        OperationImplementRectangleAdd operationImplementRectangleAdd;

        OperationImplementSliceAdd operationImplementSliceAdd;

        OperationImplementLineAdd operationImplementSliceLineAdd;

        OperationImplementBrushRemove operationImplementBrushRemove;

        OperationImplementRectangleRemove operationImplementRectangleRemove;

        OperationImplementSliceRemove operationImplementSliceRemove;

        OperationImplementLineRemove operationImplementSliceLineRemove;

        OperationImplementBrushPaint operationImplementBrushPaint;

        OperationImplementRectanglePaint operationImplementRectanglePaint;

        OperationImplementSlicePaint operationImplementSlicePaint;

        OperationImplementLinePaint operationImplementSliceLinePaint;

        OperationImplementBrushSelect operationImplementBrushSelect;
        OperationImplementRectangleSelect operationImplementRectangleSelect;
        OperationImplementLineSelect operationImplementLineSelect;
        OperationImplementSliceSelect operationImplementSliceSelect;
        OperationImplementScaleSelect operationImplementScaleSelect;

        //OperationImplementBrushAddOrPaint operationImplementBrushAdd2DEditor;

        //OperationImplementRectangleAddOrPaint operationImplementRectangleAdd2DEditor;

        //OperationImplementSliceAddOrPaint operationImplementSliceAdd2DEditor;

        //OperationImplementLineAddOrPaint operationImplementLineAdd2DEditor;

        OperationImplementRead operationImplementRead;

       public DrawVoxel3DCore nowDrawVoxel3DCore;

        DrawVoxel3DCore mainDrawVoxel3DCore;

        DrawVoxel3DCore prefabDrawVoxel3DCore;

        VoxelMetadata3D voxelMetadata3D;

        /// <summary>
        /// 尝试性添加或删除
        /// </summary>
        //private Dictionary<Vector3Int, Voxel3D> attemptDictionaryVoxels = new Dictionary<Vector3Int, Voxel3D>();

        /// <summary>
        /// 限定范围的函数
        /// </summary>
        private Func<Vector3Int, bool> funcIsContinue = (position) =>
        {
            if (position.x >= VoxelCategories.MAX_POSITION_X || position.y >= VoxelCategories.MAX_POSITION_Y || position.z >= VoxelCategories.MAX_POSITION_Z
             ||
             position.x <= VoxelCategories.MIN_POSITION_X || position.y < VoxelCategories.MIN_POSITION_Y || position.z <= VoxelCategories.MIN_POSITION_Z)
            {
                return true;
            }
            return false;
        };

        /// <summary>
        /// 获得 [限定范围的函数]
        /// </summary>
        /// <returns></returns>
        private Func<Vector3Int, bool> GetFuncIsContinue()
        {
            return FuncIsContinue;
        }

        /// <summary>
        /// 限定范围的函数
        /// </summary>
        public Func<Vector3Int, bool> FuncIsContinue
        {
            get
            {
                return funcIsContinue;
            }

            set
            {
                funcIsContinue = value;
                mainDrawVoxel3DCore.AddBlockIsContinue = FuncIsContinue;
            }
        }

        public Func<VoxelCategories.OperationBehavior> GetOperationBehavior = () => { return VoxelCategories.OperationBehavior.Add; };
        public Func<VoxelCategories.OperationBrush> GetOperationSelect = () => { return VoxelCategories.OperationBrush.Brush; };

        public OperateCreate3D(
            GameObject mainVoxel,
            GameObject meshSliceCollider, Transform mainCameraY, Material mainMaterial,
            Func<VoxelDirection> GetBrushDirection,
            Func<VoxelCategories.OperationBehavior> GetOperationBehavior,
            Func<VoxelCategories.OperationBrush> GetOperationSelect,
            Func<VoxelCategories.OperationSelectOperator> GetSelectOperator,
            Action<int> SetNowSelectUVKey,
            UIItemTransformUnitComponent mainUIItemTransformUnitComponent
            )
        {
            this.mainCameraY = mainCameraY;
            this.GetOperationBehavior = GetOperationBehavior;
            this.GetOperationSelect = GetOperationSelect;

            mainHistoryRecord = new HistoryRecordAPI<SerializeVoxelDatas, VoxelCategories.Operation>(99999);
            //封印Temp//tempHistoryRecord = new HistoryRecordAPI<SimpleVoxel>(100);
            //nowHistoryRecord = mainHistoryRecord;
            

            mainProxyOperation = new ProxyOperation(mainHistoryRecord);
            //封印Temp//tempProxyOperation = new ProxyOperation(tempHistoryRecord, mastermind.automaticSwatchesColor);
            nowProxyOperation = mainProxyOperation;

            mainDrawVoxel3DCore = new DrawVoxel3DCore(mainMaterial, "Main");//mainVoxel
            mainDrawVoxel3DCore.AddBlockIsContinue = FuncIsContinue;
            mainDrawVoxel3DCore.RootTransform.parent = mainVoxel.transform;

            //UINodeTransformComponent.thas.AddItem<UIItemTransformUnitComponent>("Main", new Vector3(0, 0, 0), new Vector3(0, 0, 0), mainVoxel.transform);

            mainDrawVoxel3DCore.mainMaterial.SetColor("_Color", new Color(1, 1, 1, 1));


            Material tempMaterial = new Material(Shader.Find("Custom/Voxel Alpha"));
            prefabDrawVoxel3DCore = new DrawVoxel3DCore(tempMaterial, "Prefab Voxel");
            tempMaterial.SetColor("_Color",new Color(1,1,1,0.5f));
            prefabDrawVoxel3DCore.AddBlockIsContinue = FuncIsContinue;

            //封印Temp//tempMaterial = UnityEngine.Object.Instantiate(mastermind.mainMaterial);
            //封印Temp//tempDrawVoxel3DCore = new DrawVoxel3DCore(tempMaterial, "Temp Voxel");
            //封印Temp//tempDrawVoxel3DCore.AddBlockIsContinue = FuncIsContinue;

            nowDrawVoxel3DCore = mainDrawVoxel3DCore;
            //drawVoxel3DCoreManager.Add("Main", mainDrawVoxel3DCore, mainProxyOperation, mainVoxel, mainUIItemTransformUnitComponent);

            drawVoxel3DCoreManager = new DrawVoxel3DCoreManager("Main", mainDrawVoxel3DCore, mainProxyOperation, mainVoxel, mainUIItemTransformUnitComponent);
            mainVoxel.gameObject.AddComponent<DrawVoxel3DCoreComponent>().MyStart(mainDrawVoxel3DCore, this,
                GameObject.FindObjectOfType<MainSkeletonComponent>().mainBone, drawVoxel3DCoreManager);


            mainUIItemTransformUnitComponent.Show("Main", new Vector3(0, 0, 0), mainVoxel.transform);

            voxelMetadata3D = VoxelMetadata3D.Instance;

            operationImplementBrushAdd = new OperationImplementBrushAdd();
            operationImplementRectangleAdd = new OperationImplementRectangleAdd();
            operationImplementSliceAdd = new OperationImplementSliceAdd(meshSliceCollider, mainCameraY, GetBrushDirection, GetFuncIsContinue);
            operationImplementSliceLineAdd = new OperationImplementLineAdd();

            operationImplementBrushRemove = new OperationImplementBrushRemove();
            operationImplementRectangleRemove = new OperationImplementRectangleRemove();
            operationImplementSliceRemove = new OperationImplementSliceRemove(meshSliceCollider, mainCameraY, GetBrushDirection);
            operationImplementSliceLineRemove = new OperationImplementLineRemove();

            operationImplementBrushPaint = new OperationImplementBrushPaint();
            operationImplementRectanglePaint = new OperationImplementRectanglePaint();
            operationImplementSlicePaint = new OperationImplementSlicePaint(meshSliceCollider, mainCameraY, GetBrushDirection);
            operationImplementSliceLinePaint = new OperationImplementLinePaint();

            operationImplementBrushSelect = new OperationImplementBrushSelect();
            operationImplementRectangleSelect = new OperationImplementRectangleSelect();
            operationImplementLineSelect = new OperationImplementLineSelect();
            operationImplementSliceSelect = new OperationImplementSliceSelect(meshSliceCollider, mainCameraY, GetBrushDirection);
            operationImplementScaleSelect = new OperationImplementScaleSelect();

            operationImplementRead = new OperationImplementRead(SetNowSelectUVKey);


            //封印Temp//operationImplementBrushAdd2DEditor = new OperationImplementBrushAddOrPaint(tempProxyOperation, tempDrawVoxel3DCore);
            //封印Temp//operationImplementRectangleAdd2DEditor = new OperationImplementRectangleAddOrPaint(tempProxyOperation, tempDrawVoxel3DCore);
            //封印Temp//operationImplementSliceAdd2DEditor = new OperationImplementSliceAddOrPaint(tempProxyOperation, tempDrawVoxel3DCore, meshSliceCollider, mainCameraY, getBrushDirection, mainDrawVoxel3DCore.allVoxels);
            //封印Temp//operationImplementLineAdd2DEditor = new OperationImplementLineAddOrPaint(tempProxyOperation, tempDrawVoxel3DCore);

            SelectNowOperationImplement();


            //var alexdata = GetFileVoxelData(mainDrawVoxel3DCore);
            //System.IO.File.WriteAllBytes(@"C:\Users\Administrator\Desktop\xxxx.vox", alexdata);
            //byte[] oldData = System.IO.File.ReadAllBytes(@"C:\Users\Administrator\Desktop\niuniu.vox");
            //for (int i = 0, max = alexdata.Length; i < max; i++)
            //{
            //    if (alexdata[i] == oldData[i])
            //    {

            //    }
            //    else
            //    {
            //        Debug.Log("!!!!!");
            //        break;
            //    }
            //}
            //Debug.Log("0o");

        }

        public Color32[] InputSlabVoxel(string path)
        {
            var data = VoxelBlock.VoxelInput.VoxelInput.GetVoxelData(path);
            List<Voxel3D> inputdata = new List<Voxel3D>();
            int sizeX, sizeY, sizeZ;
            sizeX = data.SizeX;
            sizeY = data.SizeY;
            sizeZ = data.SizeZ;
            for (int x = 0; x < sizeX; x++)
            {
                for (int y = 0; y < sizeY; y++)
                {
                    for (int z = 0; z < sizeZ; z++)
                    {
                        if (data.Voxels[x, y, z] != 255)
                        {
                            inputdata.Add(new Voxel3D(new Vector3Int(x - (sizeX / 2), y, -z + (sizeZ / 2)), data.Voxels[x, y, z]));
                        }
                    }
                }
            }
            mainDrawVoxel3DCore.DrawAddBlock(inputdata);
            mainDrawVoxel3DCore.DrawOver();
            return data.Colors;
        }

        public Vector3Int[] TestAdd(IEnumerable<Voxel3D> allp)
        {
            var array = mainDrawVoxel3DCore.DrawAddBlock(allp);
            mainDrawVoxel3DCore.DrawOver();

            Vector3Int[] list = new Vector3Int[array.Length];
            for (int i = 0; i < array.Length; i++)
            {
                list[i] = array[i].position;
            }
            return list;
        }

        public void TestRemove(IEnumerable<Vector3Int> allp)
        {
            mainDrawVoxel3DCore.DrawRemoveBlock(allp);
            mainDrawVoxel3DCore.DrawOver();
        }

        public Voxel3D TestRead(Vector3Int p)
        {
            return mainDrawVoxel3DCore.allVoxels[p];
        }

        //public bool IsSave()
        //{
        //    return mainDrawVoxel3DCore.allVoxels.Count > 0;
        //}

        /*
        public void StartTempEditor()
        {
            nowDrawVoxel3DCore = tempDrawVoxel3DCore;
            nowHistoryRecord = tempHistoryRecord;
            isTempEditor = true;
            SelectNowOperationImplement();
        }

        public void OverTempEditor()
        {
            isTempEditor = false;

            foreach (var item in tempDrawVoxel3DCore.allVoxels.Values)
            {
                item.isWrite = false;
            }

            var historyData = mainDrawVoxel3DCore.DrawAddBlock(tempDrawVoxel3DCore.allVoxels.Values);
            mainDrawVoxel3DCore.DrawOver();

            List<SimpleVoxel> historyRecordFrontList = new List<SimpleVoxel>();
            List<SimpleVoxel> historyRecordBreakList = new List<SimpleVoxel>(historyData);
            mainHistoryRecord.Write((int)VoxelCategories.Operation.Add, historyRecordFrontList, historyRecordBreakList);

            nowDrawVoxel3DCore = mainDrawVoxel3DCore;
            nowHistoryRecord = mainHistoryRecord;

            tempHistoryRecord.Clear();

            tempDrawVoxel3DCore.Clear();
        }
        */

        bool isRefresh = false;
        /// <summary>
        /// 一个手势过程中初始点击的坐标
        /// </summary>
        Vector3Int gestureStartPosition = new Vector3Int(0, 0, 0);

        /// <summary>
        /// 一帧过程中那一帧到达的坐标
        /// </summary>
        Vector3Int updateStartPosition = new Vector3Int(0, 0, 0);


        private void SelectNowOperationImplement()
        {

            if (isTempEditor)
            {
                //封印Temp//  
                /*
                switch (GetOperationBehavior())
                {
                    case VoxelCategories.OperationBehavior.Add:
                        switch (GetOperationSelect())
                        {
                            case VoxelCategories.OperationSelect.Brush:
                                nowOperationImplement = operationImplementBrushAdd2DEditor;
                                break;
                            case VoxelCategories.OperationSelect.Rectangle:
                                nowOperationImplement = operationImplementRectangleAdd2DEditor;
                                break;
                            case VoxelCategories.OperationSelect.Slice:
                                nowOperationImplement = operationImplementSliceAdd2DEditor;
                                break;
                            case VoxelCategories.OperationSelect.Line:
                                nowOperationImplement = operationImplementLineAdd2DEditor;
                                break;
                        }
                        break;
                    case VoxelCategories.OperationBehavior.Remove:
                        break;
                    case VoxelCategories.OperationBehavior.Paint:
                        break;
                    case VoxelCategories.OperationBehavior.Read:
                        break;
                }
                */
            }
            else
            {
                switch (GetOperationBehavior())
                {
                    case VoxelCategories.OperationBehavior.Add:
                        switch (GetOperationSelect())
                        {
                            case VoxelCategories.OperationBrush.Brush:
                                nowOperationImplement = operationImplementBrushAdd;
                                break;
                            case VoxelCategories.OperationBrush.Rectangle:
                                nowOperationImplement = operationImplementRectangleAdd;
                                break;
                            case VoxelCategories.OperationBrush.Slice:
                                nowOperationImplement = operationImplementSliceAdd;
                                break;
                            case VoxelCategories.OperationBrush.Line:
                                nowOperationImplement = operationImplementSliceLineAdd;
                                break;
                        }
                        break;
                    case VoxelCategories.OperationBehavior.Remove:
                        switch (GetOperationSelect())
                        {
                            case VoxelCategories.OperationBrush.Brush:
                                nowOperationImplement = operationImplementBrushRemove;
                                break;
                            case VoxelCategories.OperationBrush.Rectangle:
                                nowOperationImplement = operationImplementRectangleRemove;
                                break;
                            case VoxelCategories.OperationBrush.Slice:
                                nowOperationImplement = operationImplementSliceRemove;
                                break;
                            case VoxelCategories.OperationBrush.Line:
                                nowOperationImplement = operationImplementSliceLineRemove;
                                break;
                        }
                        break;
                    case VoxelCategories.OperationBehavior.Paint:
                        switch (GetOperationSelect())
                        {
                            case VoxelCategories.OperationBrush.Brush:
                                nowOperationImplement = operationImplementBrushPaint;
                                break;
                            case VoxelCategories.OperationBrush.Rectangle:
                                nowOperationImplement = operationImplementRectanglePaint;
                                break;
                            case VoxelCategories.OperationBrush.Slice:
                                nowOperationImplement = operationImplementSlicePaint;
                                break;
                            case VoxelCategories.OperationBrush.Line:
                                nowOperationImplement = operationImplementSliceLinePaint;
                                break;
                        }
                        break;
                    case VoxelCategories.OperationBehavior.Select:
                        switch (GetOperationSelect())
                        {
                            case VoxelCategories.OperationBrush.Brush:
                                nowOperationImplement = operationImplementBrushSelect;
                                break;
                            case VoxelCategories.OperationBrush.Rectangle:
                                nowOperationImplement = operationImplementRectangleSelect; 
                                break;
                            case VoxelCategories.OperationBrush.Slice:
                                nowOperationImplement = operationImplementSliceSelect;
                                break;
                            case VoxelCategories.OperationBrush.Line:
                                nowOperationImplement = operationImplementLineSelect;
                                break;
                            case VoxelCategories.OperationBrush.Scale:
                                nowOperationImplement = operationImplementScaleSelect;
                                break;
                        }
                        break;
                    case VoxelCategories.OperationBehavior.Read:
                        nowOperationImplement = operationImplementRead;
                        break;
                }
            }
        }

        public void OperationStart(Vector3Int NowSelectPosition, int nowSelectUVKey)
        {
            SelectNowOperationImplement();
            
            gestureStartPosition = NowSelectPosition;
            updateStartPosition = gestureStartPosition;

            OperationImplement.StartArg arg = new OperationImplement.StartArg();
            arg.StartPosition = gestureStartPosition - (Vector3Int)nowDrawVoxel3DCore.RootTransform.position;
            arg.nowSelectUVKey = nowSelectUVKey;
            arg.nowDrawVoxel3DCore = nowDrawVoxel3DCore;
            arg.selectOperator = VoxelEditorMastermind.instance.SelectOperator;
            arg.startSliceArg = VoxelEditorMastermind.instance.StartSliceArg;
            arg.proxy = nowProxyOperation;
            nowOperationImplement.Start(arg);
        }

        public void OperationRun(Vector3Int NowSelectPosition, int nowSelectUVKey)
        {

            OperationImplement.RunArg arg = new OperationImplement.RunArg();
            arg.gestureStartPosition = gestureStartPosition - (Vector3Int)nowDrawVoxel3DCore.RootTransform.position;
            arg.updateStartPosition = updateStartPosition - (Vector3Int)nowDrawVoxel3DCore.RootTransform.position;
            arg.nowSelectPosition = NowSelectPosition - (Vector3Int)nowDrawVoxel3DCore.RootTransform.position;
            arg.nowSelectUVKey = nowSelectUVKey;
            nowOperationImplement.Run(arg);

            updateStartPosition = NowSelectPosition;
        }

        public void OperationOver(Vector3Int NowSelectPosition, int nowSelectUVKey, bool isStop)
        {
            nowOperationImplement.IsStop = isStop;
            OperationImplement.OverArg arg = new OperationImplement.OverArg();
            arg.gestureStartPosition = gestureStartPosition - (Vector3Int)nowDrawVoxel3DCore.RootTransform.position;
            arg.updateStartPosition = updateStartPosition - (Vector3Int)nowDrawVoxel3DCore.RootTransform.position;
            arg.nowSelectPosition = NowSelectPosition - (Vector3Int)nowDrawVoxel3DCore.RootTransform.position;
            arg.nowSelectUVKey = nowSelectUVKey;
            nowOperationImplement.Over(arg);

            DrawOver();
        }

        public void OperationStop(Vector3Int NowSelectPosition, int nowSelectUVKey)
        {
            updateStartPosition = NowSelectPosition;
        }

        private void DrawOver()
        {
            nowDrawVoxel3DCore.DrawOver();
        }

        //public void Clear()
        //{
        //    nowDrawVoxel3DCore.Clear();
        //}

        public void Hide()
        {
            nowDrawVoxel3DCore.RootTransform.gameObject.SetActive(false);
        }

        public void Show()
        {
            nowDrawVoxel3DCore.RootTransform.gameObject.SetActive(true);
        }


        public void Revoke()
        {
            var data = nowProxyOperation.Revoke();
            if (data == null)
            {
                return;
            }
            //VoxelCategories.Operation operation = (VoxelCategories.Operation)data.m_Operation;
            //switch (operation)
            //{
            //    case VoxelCategories.Operation.Not:
            //        break;
            //    case VoxelCategories.Operation.Add:
            //        break;
            //    case VoxelCategories.Operation.Remove:
            //        break;
            //    case VoxelCategories.Operation.Paint:
            //        break;
            //    case VoxelCategories.Operation.AddOrPaint:
            //        break;
            //    default:
            //        break;
            //}
            if (data.m_Operation == VoxelCategories.Operation.Add)
            {
                List<Vector3Int> array = new List<Vector3Int>(data.m_BreakData.voxels.Count());
                foreach (SimpleVoxel item in data.m_BreakData.voxels)
                {
                    array.Add(item.position);
                }
                nowDrawVoxel3DCore.DrawRemoveBlock(array);
                DrawOver();
            }
            else if (data.m_Operation == VoxelCategories.Operation.Remove)
            {
                List<Voxel3D> array = new List<Voxel3D>(data.m_FrontData.voxels.Count());
                foreach (SimpleVoxel item in data.m_FrontData.voxels)
                {
                    array.Add(new Voxel3D(item.position, item.uvKey, item.selectKey));
                }
                nowDrawVoxel3DCore.DrawAddBlock(array);
                DrawOver();
            }
            else if (data.m_Operation == VoxelCategories.Operation.Paint)
            {
                nowDrawVoxel3DCore.DrawPaintBlock(data.m_FrontData.voxels);
                //DrawOver();
            }
            else if (data.m_Operation == VoxelCategories.Operation.AddOrPaint)
            {
                List<Vector3Int> array = new List<Vector3Int>(data.m_BreakData.voxels.Count());
                foreach (SimpleVoxel item in data.m_BreakData.voxels)
                {
                    array.Add(item.position);
                }
                nowDrawVoxel3DCore.DrawRemoveBlock(array);


                List<Voxel3D> array2 = new List<Voxel3D>(data.m_FrontData.voxels.Count());
                foreach (SimpleVoxel item in data.m_FrontData.voxels)
                {
                    array2.Add(new Voxel3D(item.position, item.uvKey));
                }
                nowDrawVoxel3DCore.DrawAddBlock(array2);

                DrawOver();
            }
            else if (data.m_Operation == VoxelCategories.Operation.SelectAdd)
            {
                nowDrawVoxel3DCore.DrawSelect(data.m_BreakData.positions, 255);
            }
            else if (data.m_Operation == VoxelCategories.Operation.SelectRemove)
            {
                nowDrawVoxel3DCore.DrawSelect(data.m_FrontData.positions, 1);
            }

        }

        public void BackRevoke()
        {
            var data = nowProxyOperation.BackRevoke();
            if (data == null)
            {
                return;
            }


            if (data.m_Operation == VoxelCategories.Operation.Add)
            {
                //List<Voxel3D> array = new List<Voxel3D>(data.m_BreakData.voxels.Count());
                //foreach (SimpleVoxel item in data.m_BreakData.voxels)
                //{
                //    array.Add(new Voxel3D(item.position, item.uvKey));
                //}
                nowDrawVoxel3DCore.DrawAddBlock(data.m_BreakData.voxels);

                DrawOver();
            }
            else if (data.m_Operation == VoxelCategories.Operation.Remove)
            {
                List<Vector3Int> array = new List<Vector3Int>(data.m_FrontData.voxels.Count());
                foreach (SimpleVoxel item in data.m_FrontData.voxels)
                {
                    array.Add(item.position);
                }
                nowDrawVoxel3DCore.DrawRemoveBlock(array);

                DrawOver();
            }
            else if (data.m_Operation == VoxelCategories.Operation.Paint)
            {
                nowDrawVoxel3DCore.DrawPaintBlock(data.m_BreakData.voxels);
                DrawOver();
            }
            else if (data.m_Operation == VoxelCategories.Operation.AddOrPaint)
            {
                List<Vector3Int> array2 = new List<Vector3Int>(data.m_FrontData.voxels.Count());
                foreach (SimpleVoxel item in data.m_FrontData.voxels)
                {
                    array2.Add(item.position);
                }
                nowDrawVoxel3DCore.DrawRemoveBlock(array2);
                nowDrawVoxel3DCore.DrawAddBlock(data.m_BreakData.voxels);


                DrawOver();
            }
            else if (data.m_Operation == VoxelCategories.Operation.SelectAdd)
            {
                nowDrawVoxel3DCore.DrawSelect(data.m_BreakData.positions, 1);
            }
            else if (data.m_Operation == VoxelCategories.Operation.SelectRemove)
            {
                nowDrawVoxel3DCore.DrawSelect(data.m_FrontData.positions, 255);
            }

        }






        public void NowEditorMain()
        {
            nowProxyOperation = mainProxyOperation;
            nowDrawVoxel3DCore = mainDrawVoxel3DCore;
        }


        public void ClearAll()
        {
            mainDrawVoxel3DCore.Clear();

            TransformVector.Thas.Look = null;

            drawVoxel3DCoreManager.ClearAll();

            nowProxyOperation = mainProxyOperation;
            nowDrawVoxel3DCore = mainDrawVoxel3DCore;
            nowProxyOperation.Clear();
        }

        public void DeleteSave(string fileName, SaveReadWrite saveReadWrite)
        {
            saveReadWrite.Delete(fileName);
        }

        //public void ReadSave(string fileName, SaveReadWrite saveReadWrite, Texture2D EditingTex)
        //{
        //    nowProxyOperation.Clear();
        //    nowDrawVoxel3DCore.Clear();
        //    nowDrawVoxel3DCore.DrawAddBlock(saveReadWrite.Read(fileName, nowProxyOperation, EditingTex));
        //    nowDrawVoxel3DCore.DrawOver();
        //}
        public void ClearSelect()
        {
            var list = nowDrawVoxel3DCore.ClearAllSelect();
            nowProxyOperation.Write( VoxelCategories.Operation.SelectRemove, list, new Vector3Int[] { });
        }

        public void WriteSave(string fileName, SaveReadWrite saveReadWrite, Texture2D userTexture, VoxelBlock.VoxelInput.RioVoxelData riovox, ProxyOperation[] allOverProxyOperation)
        {
            saveReadWrite.Write(fileName, allOverProxyOperation, riovox, userTexture);
        }

        public void ReadPrefab (string fileName, SaveReadWrite saveReadWrite)
        {
            prefabDrawVoxel3DCore.Clear();
            prefabDrawVoxel3DCore.DrawAddBlock(saveReadWrite.ReadVox(fileName));
            prefabDrawVoxel3DCore.RecalculateNormalsAndUpdateCollider();
            prefabDrawVoxel3DCore.mainMaterial.mainTexture = mainDrawVoxel3DCore.mainMaterial.mainTexture;
        }

        /// <summary>
        /// 分离
        /// </summary>
        public void Separate()
        {
            var removeList = nowDrawVoxel3DCore.Separate();
            if (removeList.Count <= 0)
            {
                return;
            }
            nowProxyOperation.Write(VoxelCategories.Operation.Remove, removeList, new SimpleVoxel[] { });
            nowDrawVoxel3DCore.DrawOver();

            SimpleVoxel[] addList = new SimpleVoxel[removeList.Count];

            Material tempMaterial = GameObject.Instantiate(mainDrawVoxel3DCore.mainMaterial); //new Material(Shader.Find("Custom/Voxel Alpha"));
            tempMaterial.renderQueue++;
            DrawVoxel3DCore tempDrawVoxel3DCore = new DrawVoxel3DCore(tempMaterial, "Temp Voxel");
            tempMaterial.SetColor("_Color", new Color(1, 1, 1, 0.67f));
            tempMaterial.SetFloat("_Power", -0.001f);
            tempDrawVoxel3DCore.AddBlockIsContinue = FuncIsContinue;
            for (int i = 0; i < addList.Length; i++)
            {
                addList[i] = new SimpleVoxel(removeList[i].position, removeList[i].uvKey, 255);
            }
            tempDrawVoxel3DCore.DrawAddBlock(addList);
            tempDrawVoxel3DCore.RecalculateNormalsAndUpdateCollider();

            tempDrawVoxel3DCore.mainMaterial.mainTexture = nowDrawVoxel3DCore.mainMaterial.mainTexture;

            var dataPosition = BasicAlgorithm.GetMaxMinPosition(addList);
            Vector3 position = ((Vector3)(dataPosition.Item1 + dataPosition.Item2)) / 2;

            int id = 0;
            while (GameObject.Find("Part" + id))
            {
                id++;
            }
            string voxelEditorName = "Part" + id;

            //id = 0;
            //while (drawVoxel3DCoreManager.allProxy.ContainsKey(voxelEditorName))
            //{
            //    voxelEditorName += id;
            //    id++;
            //}


            GameObject root = new GameObject(voxelEditorName);
            tempDrawVoxel3DCore.RootTransform.SetParent(root.transform);
            tempDrawVoxel3DCore.RootTransform.localPosition = -position;

            
            position += (drawVoxel3DCoreManager.allCore[nowDrawVoxel3DCore].ui.Position + nowDrawVoxel3DCore.RootTransform.localPosition);
            root.transform.position = position; 
            root.AddComponent<DrawVoxel3DCoreComponent>().MyStart(tempDrawVoxel3DCore, this, drawVoxel3DCoreManager);


            UIItemTransformUnitComponent ui;
            UINodeTransformComponent.thas.AddItem(voxelEditorName, position, dataPosition.Item2, root.transform, typeof(UIItemTransformUnitComponent),out ui);

            ProxyOperation tempProxyOperation = new ProxyOperation(new HistoryRecordAPI<SerializeVoxelDatas, VoxelCategories.Operation>(100));
            drawVoxel3DCoreManager.Add(voxelEditorName, tempDrawVoxel3DCore, tempProxyOperation, root, ui);//放逐

            TransformVector.Thas.Look = root.transform;

            //重设被分离的物体的节点
            if (nowDrawVoxel3DCore != mainDrawVoxel3DCore)
            {
                dataPosition = BasicAlgorithm.GetMaxMinPosition(nowDrawVoxel3DCore.allVoxels.Values);
                position = ((Vector3)(dataPosition.Item1 + dataPosition.Item2)) / 2;
                Transform nowRoot = nowDrawVoxel3DCore.RootTransform.root;
                Vector3 newPosition = nowRoot.position + position + nowDrawVoxel3DCore.RootTransform.localPosition;
                nowRoot.gameObject.GetComponent<TransformUnitComponent>().zeroPosition = position;
                nowRoot.gameObject.GetComponent<TransformUnitComponent>().minPosition = dataPosition.Item2;
                nowRoot.gameObject.GetComponent<TransformUnitComponent>().SetPosition(newPosition);

                nowRoot.position = newPosition;

                nowDrawVoxel3DCore.RootTransform.localPosition = -position;
            }
            TransformVector.Thas.Look = root.transform;
        }

        public bool Merge(DrawVoxel3DCore aDrawVoxel3DCore)
        {
            if (nowDrawVoxel3DCore == aDrawVoxel3DCore)
            {
                return false;
            }
            var inputDatas = aDrawVoxel3DCore.allVoxels.Values;
            Vector3Int position = aDrawVoxel3DCore.RootTransform.position;
            List<Voxel3D> trueInputDatas = new List<Voxel3D>();
            foreach (var item in inputDatas)
            {
                trueInputDatas.Add(new Voxel3D(item.worldPosition + position, item.uvKey));
            }
            var allList = nowDrawVoxel3DCore.DrawAddBlock(trueInputDatas);
            nowDrawVoxel3DCore.DrawOver();
            nowProxyOperation.Write(VoxelCategories.Operation.Add,  new SimpleVoxel[] { }, allList);
            return true;
        }

        //UnitMeshPointComponent
        public void AddPart(string name, IEnumerable<Voxel3D> voxel, Vector3 zeroPosition, Vector3 worldPosition, Vector3 minPosition, bool isBone, Vector3 bonePosition, ProxyOperation proxyOperation)
        {
            if (name.Equals("Main"))
            {
                mainDrawVoxel3DCore.DrawAddBlock(voxel);
                mainDrawVoxel3DCore.DrawOver();
                drawVoxel3DCoreManager.mainDrawVoxel3DCoreValue.ui.Position = worldPosition;
                drawVoxel3DCoreManager.mainDrawVoxel3DCoreValue.component.transform.root.position = worldPosition;
                if (proxyOperation == null)
                {

                }
                else
                {
                    drawVoxel3DCoreManager.mainDrawVoxel3DCoreValue.proxy = proxyOperation;
                    mainProxyOperation = proxyOperation;
                }

                if (isBone)
                {
                    VoxelEditorMastermind.instance.mainVoxel.GetComponent<UnitMeshPointComponent>().m_boneTarget.transform.localPosition = bonePosition;
                }
                return;
            }


            Material tempMaterial = GameObject.Instantiate(mainDrawVoxel3DCore.mainMaterial); //new Material(Shader.Find("Custom/Voxel Alpha"));
            tempMaterial.renderQueue++;
            DrawVoxel3DCore tempDrawVoxel3DCore = new DrawVoxel3DCore(tempMaterial, "Temp Voxel");
            tempMaterial.SetColor("_Color", new Color(1, 1, 1, 0.67f));
            tempMaterial.SetFloat("_Power", -0.001f);
            tempDrawVoxel3DCore.AddBlockIsContinue = FuncIsContinue;
            tempDrawVoxel3DCore.DrawAddBlock(voxel);
            tempDrawVoxel3DCore.DrawOver();

            tempDrawVoxel3DCore.mainMaterial.mainTexture = nowDrawVoxel3DCore.mainMaterial.mainTexture;


            GameObject root = new GameObject(name);
            root.transform.position = worldPosition;
            tempDrawVoxel3DCore.RootTransform.SetParent(root.transform);
            root.AddComponent<DrawVoxel3DCoreComponent>().MyStart(tempDrawVoxel3DCore, this, drawVoxel3DCoreManager);
            tempDrawVoxel3DCore.RootTransform.localPosition = -zeroPosition;

            UIItemTransformUnitComponent ui;
            TransformUnitComponent fmTransformUnitComponent = UINodeTransformComponent.thas.AddItem
                (name, worldPosition, minPosition, root.transform, typeof(UIItemTransformUnitDrawVoxelComponent),out ui);

            if (proxyOperation == null)
            {
                ProxyOperation tempProxyOperation = new ProxyOperation(new HistoryRecordAPI<SerializeVoxelDatas, VoxelCategories.Operation>(100));
                drawVoxel3DCoreManager.Add(name, tempDrawVoxel3DCore, tempProxyOperation, root, ui);
            }
            else
            {
                drawVoxel3DCoreManager.Add(name, tempDrawVoxel3DCore, proxyOperation, root, ui);
            }

            root.gameObject.GetComponent<TransformUnitComponent>().zeroPosition = zeroPosition;
            root.gameObject.GetComponent<TransformUnitComponent>().minPosition = minPosition;
            root.gameObject.GetComponent<TransformUnitComponent>().SetPosition(worldPosition);
            if (isBone)
            {
                ((UIItemTransformUnitDrawVoxelComponent)fmTransformUnitComponent.UiComponent).CreateCustomBone(bonePosition);
            }
        }


        //public void Merge(DrawVoxel3DCore aDrawVoxel3DCore, DrawVoxel3DCore bDrawVoxel3DCore)
        //{
        //    var allList = bDrawVoxel3DCore.DrawAddBlock(aDrawVoxel3DCore.allVoxels.Values);
        //    bDrawVoxel3DCore.DrawOver();
        //}

        public void EsitorChange(DrawVoxel3DCore aDrawVoxel3DCore)
        {
            nowDrawVoxel3DCore.mainMaterial.SetColor("_Color", new Color(1, 1, 1, 0.67f));
            aDrawVoxel3DCore.mainMaterial.SetColor("_Color", new Color(1, 1, 1, 1));
            aDrawVoxel3DCore.mainMaterial.renderQueue = 2001;
            nowDrawVoxel3DCore.mainMaterial.renderQueue = 2002;

            nowDrawVoxel3DCore = aDrawVoxel3DCore;
            nowProxyOperation = drawVoxel3DCoreManager.allCore[aDrawVoxel3DCore].proxy;
        }

        public VoxelInput.VoxelInputInfo GetFileVoxelMainData()
        {
            return GetFileVoxelData(mainDrawVoxel3DCore);
        }
        public static VoxelInput.VoxelInputInfo GetFileVoxelData(DrawVoxel3DCore aDrawVoxel3DCore)
        {
            var dataPosition = BasicAlgorithm.GetMaxMinPosition(aDrawVoxel3DCore.allVoxels.Values);
            var minV = dataPosition.Item2;
            var maxV = dataPosition.Item1;
            int sizeX = maxV.x - minV.x;
            int sizeY = maxV.y - minV.y;
            int sizeZ = maxV.z - minV.z;
            sizeX++;
            sizeY++;
            sizeZ++;

            int[,,] voxels = new int[sizeX, sizeY, sizeZ];
            Color32[] colors = VoxelEditorMastermind.instance.EditingTex.GetPixels32();

            VoxelInput.VoxelInput data = new VoxelInput.VoxelInput();// VoxelBlock.VoxelInput.VoxelInput.GetVoxelData(@"C:\Users\Administrator\Desktop\niuniu.vox");
            for (int x = 0; x < sizeX; x++)
            {
                for (int y = 0; y < sizeY; y++)
                {
                    for (int z = 0; z < sizeZ; z++)
                    {
                        //var item = aDrawVoxel3DCore.allVoxels[new Vector3Int(x, y, z) - minV];
                        //if (item == null)
                        //{
                        //    voxels[x, y, z] = 255;
                        //}
                        //else
                        //{
                        //    voxels[x, y, z] = item.uvKey;
                        //}
                       voxels[x, y, z] = 255;
                    }
                }
            }
            foreach (var item in aDrawVoxel3DCore.allVoxels.Values)
            {
                var v = item.worldPosition;
                voxels[v.x - minV.x, v.y - minV.y, v.z - minV.z] = item.uvKey;
            }        

            VoxelInput.VoxelInputInfo newVoxelData = new VoxelInput.VoxelInputInfo();
            newVoxelData.Colors = colors;
            newVoxelData.Voxels = voxels;
            newVoxelData.SizeX = sizeX;
            newVoxelData.SizeY = sizeY;
            newVoxelData.SizeZ = sizeZ;
            newVoxelData.minX = minV.x;
            newVoxelData.minY = minV.y;
            newVoxelData.minZ = minV.z;
            return newVoxelData;
        }


    }

}